/*
 *  蓝桥杯模拟赛题目 通电， 最小生成树 Prim算法
 * */
#include <iostream>
#include <cmath>
#include <cstring>
#include <iomanip>

using namespace std;

const int N = 1010;
int n;

struct {
    double lowestcost;
    int start;
    int x, y, h;
} node[N];

double map[N][N];

double prim() {
    double sum = 0;

    double mincost;
    int mind;
    for (int i = 2; i <= n; ++i) {
        node[i].lowestcost = map[1][i];
        node[i].start = 1;
    }
    node[1].lowestcost = 0;
    for (int i = 2; i <= n; ++i) {
        mincost = 0x3f3f3f3f;
        mind = 0;
        for (int j = 2; j <= n; ++j) {
            if (node[j].lowestcost != 0 && node[j].lowestcost < mincost) {
                mincost = node[j].lowestcost;
                mind = j;
            }
        }
        sum += mincost;
        node[mind].lowestcost = 0;
        for (int j = 2; j <= n; ++j) {
            if (map[mind][j] < node[j].lowestcost) {
                node[j].lowestcost = map[mind][j];
                node[j].start = mind;
            }
        }
    }

    return sum;
}

int main() {

    memset(map, 0x3f, sizeof map);
    cin >> n;

    for (int i = 1; i <= n; ++i) {
        cin >> node[i].x >> node[i].y >> node[i].h;
    }

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j < i; ++j) {
            map[i][j] = map[j][i] = sqrt((node[i].x - node[j].x) * (node[i].x - node[j].x) +
                                         (node[i].y - node[j].y) * (node[i].y - node[j].y))
                                    + (node[i].h - node[j].h) * (node[i].h - node[j].h);
        }
    }

    auto res = prim();
    cout << fixed << setprecision(2) << res << endl;
    return 0;
}